/**
 * 语音检测服务层
 */
const detectionDao = require('../dao/detectionDao');
const evaluationDao = require('../dao/evaluationDao');
const { validatePagination, validateEnum } = require('../utils/validation');

/**
 * 获取检测文本服务
 * @param {Object} query - 查询参数
 * @returns {Object} 检测文本分页结果
 */
const getDetectionTexts = async (query) => {
  const { page, limit } = validatePagination(query);
  const { category, difficulty } = query;

  // 验证难度参数
  if (difficulty) {
    const difficultyValidation = validateEnum(difficulty, ['easy', 'medium', 'hard'], '难度');
    if (!difficultyValidation.isValid) {
      throw new Error(difficultyValidation.message);
    }
  }

  const options = {
    page,
    limit,
    category,
    difficulty,
    is_active: true
  };

  const result = await detectionDao.getDetectionTexts(options);

  const formattedList = result.texts.map(text => ({
    id: text.id,
    title: text.title,
    content: text.content,
    pinyin: text.pinyin,
    category: text.category,
    difficulty: text.difficulty,
    duration: text.duration || 0,
    tags: text.tags || [],
    createdAt: text.created_at
  }));

  return {
    list: formattedList,
    total: result.total,
    page,
    limit
  };
};

/**
 * 获取随机检测文本服务
 * @param {Object} filters - 筛选条件
 * @returns {Object} 随机检测文本
 */
const getRandomDetectionText = async (filters = {}) => {
  const { category, difficulty } = filters;

  // 验证难度参数
  if (difficulty) {
    const difficultyValidation = validateEnum(difficulty, ['easy', 'medium', 'hard'], '难度');
    if (!difficultyValidation.isValid) {
      throw new Error(difficultyValidation.message);
    }
  }

  const text = await detectionDao.getRandomDetectionText({
    category,
    difficulty,
    is_active: true
  });

  if (!text) {
    throw new Error('暂无可用的检测文本');
  }

  return {
    id: text.id,
    title: text.title,
    content: text.content,
    pinyin: text.pinyin,
    category: text.category,
    difficulty: text.difficulty,
    duration: text.duration || 0,
    tags: text.tags || []
  };
};

/**
 * 提交语音评测服务
 * @param {number} userId - 用户ID
 * @param {Object} evaluationData - 评测数据
 * @returns {Object} 评测结果
 */
const submitAudioEvaluation = async (userId, evaluationData) => {
  const { textId, audioFile, audioUrl } = evaluationData;

  // 检查检测文本是否存在
  const detectionText = await detectionDao.getDetectionTextById(textId);
  if (!detectionText) {
    throw new Error('检测文本不存在');
  }

  // 模拟语音评测处理（实际项目中需要调用语音识别API）
  const mockEvaluationResult = await performMockEvaluation(detectionText.content, audioFile);

  // 保存评测记录
  const evaluationRecord = await evaluationDao.createEvaluation({
    user_id: userId,
    text_id: textId,
    audio_url: audioUrl,
    original_text: detectionText.content,
    recognized_text: mockEvaluationResult.recognizedText,
    overall_score: mockEvaluationResult.overallScore,
    pronunciation_score: mockEvaluationResult.pronunciationScore,
    fluency_score: mockEvaluationResult.fluencyScore,
    accuracy_score: mockEvaluationResult.accuracyScore,
    completeness_score: mockEvaluationResult.completenessScore,
    detailed_scores: mockEvaluationResult.detailedScores,
    suggestions: mockEvaluationResult.suggestions,
    duration: mockEvaluationResult.duration,
    created_at: new Date()
  });

  return {
    id: evaluationRecord.id,
    textId: textId,
    originalText: detectionText.content,
    recognizedText: mockEvaluationResult.recognizedText,
    overallScore: mockEvaluationResult.overallScore,
    scores: {
      pronunciation: mockEvaluationResult.pronunciationScore,
      fluency: mockEvaluationResult.fluencyScore,
      accuracy: mockEvaluationResult.accuracyScore,
      completeness: mockEvaluationResult.completenessScore
    },
    detailedScores: mockEvaluationResult.detailedScores,
    suggestions: mockEvaluationResult.suggestions,
    duration: mockEvaluationResult.duration,
    createdAt: evaluationRecord.created_at
  };
};

/**
 * 获取评测历史服务
 * @param {number} userId - 用户ID
 * @param {Object} query - 查询参数
 * @returns {Object} 评测历史分页结果
 */
const getEvaluationHistory = async (userId, query) => {
  const { page, limit } = validatePagination(query);
  const { category, startDate, endDate } = query;

  const options = {
    user_id: userId,
    category,
    start_date: startDate,
    end_date: endDate,
    page,
    limit
  };

  const result = await evaluationDao.getUserEvaluations(options);

  const formattedList = result.evaluations.map(evaluation => ({
    id: evaluation.id,
    textId: evaluation.text_id,
    textTitle: evaluation.detection_text ? evaluation.detection_text.title : '',
    originalText: evaluation.original_text,
    recognizedText: evaluation.recognized_text,
    overallScore: evaluation.overall_score,
    scores: {
      pronunciation: evaluation.pronunciation_score,
      fluency: evaluation.fluency_score,
      accuracy: evaluation.accuracy_score,
      completeness: evaluation.completeness_score
    },
    duration: evaluation.duration,
    createdAt: evaluation.created_at
  }));

  return {
    list: formattedList,
    total: result.total,
    page,
    limit
  };
};

/**
 * 获取评测详情服务
 * @param {number} userId - 用户ID
 * @param {number} evaluationId - 评测ID
 * @returns {Object} 评测详情
 */
const getEvaluationDetail = async (userId, evaluationId) => {
  const evaluation = await evaluationDao.getEvaluationById(evaluationId);
  
  if (!evaluation) {
    throw new Error('评测记录不存在');
  }

  if (evaluation.user_id !== userId) {
    throw new Error('无权访问该评测记录');
  }

  return {
    id: evaluation.id,
    textId: evaluation.text_id,
    textTitle: evaluation.detection_text ? evaluation.detection_text.title : '',
    originalText: evaluation.original_text,
    recognizedText: evaluation.recognized_text,
    audioUrl: evaluation.audio_url,
    overallScore: evaluation.overall_score,
    scores: {
      pronunciation: evaluation.pronunciation_score,
      fluency: evaluation.fluency_score,
      accuracy: evaluation.accuracy_score,
      completeness: evaluation.completeness_score
    },
    detailedScores: evaluation.detailed_scores,
    suggestions: evaluation.suggestions,
    duration: evaluation.duration,
    createdAt: evaluation.created_at
  };
};

/**
 * 获取排行榜服务
 * @param {Object} query - 查询参数
 * @returns {Object} 排行榜数据
 */
const getLeaderboard = async (query) => {
  const { type = 'overall', period = 'week', page, limit } = query;
  const { page: validPage, limit: validLimit } = validatePagination({ page, limit });

  // 验证排行榜类型
  const typeValidation = validateEnum(type, ['overall', 'pronunciation', 'fluency', 'accuracy'], '排行榜类型');
  if (!typeValidation.isValid) {
    throw new Error(typeValidation.message);
  }

  // 验证时间周期
  const periodValidation = validateEnum(period, ['day', 'week', 'month', 'all'], '时间周期');
  if (!periodValidation.isValid) {
    throw new Error(periodValidation.message);
  }

  const result = await evaluationDao.getLeaderboard({
    type,
    period,
    page: validPage,
    limit: validLimit
  });

  const formattedList = result.rankings.map((ranking, index) => ({
    rank: (validPage - 1) * validLimit + index + 1,
    userId: ranking.user_id,
    username: ranking.user ? ranking.user.username : '',
    nickname: ranking.user ? ranking.user.nickname : '',
    avatar: ranking.user ? ranking.user.avatar : '',
    score: ranking.average_score,
    evaluationCount: ranking.evaluation_count,
    totalDuration: ranking.total_duration
  }));

  return {
    list: formattedList,
    total: result.total,
    page: validPage,
    limit: validLimit
  };
};

/**
 * 模拟语音评测处理（实际项目中需要替换为真实的语音识别API）
 * @param {string} originalText - 原始文本
 * @param {Object} audioFile - 音频文件
 * @returns {Object} 评测结果
 */
const performMockEvaluation = async (originalText, audioFile) => {
  // 模拟处理延时
  await new Promise(resolve => setTimeout(resolve, 1000));

  // 模拟评测结果
  const overallScore = Math.floor(Math.random() * 30) + 70; // 70-100分
  const pronunciationScore = Math.floor(Math.random() * 25) + 75;
  const fluencyScore = Math.floor(Math.random() * 25) + 75;
  const accuracyScore = Math.floor(Math.random() * 25) + 75;
  const completenessScore = Math.floor(Math.random() * 20) + 80;

  return {
    recognizedText: originalText, // 模拟识别结果
    overallScore,
    pronunciationScore,
    fluencyScore,
    accuracyScore,
    completenessScore,
    detailedScores: originalText.split('').map((char, index) => ({
      character: char,
      score: Math.floor(Math.random() * 30) + 70,
      position: index
    })),
    suggestions: [
      '注意声调的准确性',
      '语速可以稍微放慢一些',
      '某些字音需要更加清晰'
    ],
    duration: Math.floor(Math.random() * 10) + 5 // 5-15秒
  };
};

module.exports = {
  getDetectionTexts,
  getRandomDetectionText,
  submitAudioEvaluation,
  getEvaluationHistory,
  getEvaluationDetail,
  getLeaderboard
};
